/*******************************************************************************
 * file  : mem alloc cfg
 * creat : apleilx
 * data  : 2021/09/26
 *******************************************************************************/
#include "mem_block_alloc.h"
#include "multi_malloc.h"
#include "sys_init.h"
#include "os_obj.h"
#include "common.h"

/*******************************************************************************
 * @brief  CCM LOCK.
 *******************************************************************************/
uu16 mem_ram_lock(void)
{
	uu16 st;

	if (osOK == tx_mutex_get(os_obj.mid_mem, ms_ticks(2000)))
		st = 0;
	else
		st = 1;

	return st;
}

/*******************************************************************************
 * @brief   UNLOCK.
 *******************************************************************************/
void mem_ram_unlock(void)
{
	tx_mutex_put(os_obj.mid_mem);
}

/*******************************************************************************
 * @brief  创建内存池 SRAM.
 *******************************************************************************/
#define SRAM_SIZE (60 * 1024UL)
#define SRAM_BLOCK_SIZE (128UL)

// uu64 sram_map[SRAM_SIZE / 8] /*OBJ_SECTION(".sram")*/;			 // 内存池
// uu16 sram_tab[SRAM_SIZE / SRAM_BLOCK_SIZE] /*OBJ_SECTION(".sram")*/; // 内存分配表
#define sram_map (uu64 *)(0x20000000 + 0x18000 + 4 * 1024) // 内存池
#define sram_tab (uu16 *)(0x20000000 + 0x18000)			   // 内存分配表
multi_malloc_info_type sram_info = {0};					   // 工作信息
uu16 sram_lock(void) { return 0; }						   // 申请互斥锁
void sram_unlock(void) {}								   // 释放互斥锁
multi_malloc_api_ref(mem_sram);							   // 接口引用声明
const multi_malloc_type mem_sram = {					   // 信息描述
	sram_map,
	sram_tab,
	SRAM_SIZE,
	SRAM_BLOCK_SIZE,
	SRAM_SIZE / SRAM_BLOCK_SIZE,
	mem_ram_lock,
	mem_ram_unlock,
	&sram_info,
	multi_malloc_api_name(mem_sram)};
multi_malloc_api_make(mem_sram); // 创建API接口

/*******************************************************************************
 * @brief  创建内存池 DRAM.
 *******************************************************************************/
#define DRAM_SIZE (32 * 1024 * 1024UL - 256 * 1024UL)
#define DRAM_BLOCK_SIZE (512UL)

#define dram_map (void *)(0x80000000 + 128 * 1024) // 内存池
#define dram_tab (void *)(0x80000000)			   // 内存分配表
multi_malloc_info_type dram_info = {0};			   // 工作信息
uu16 dram_lock(void) { return 0; }				   // 申请互斥锁
void dram_unlock(void) {}						   // 释放互斥锁
multi_malloc_api_ref(mem_dram);					   // 接口引用声明
const multi_malloc_type mem_dram = {			   // 信息描述
	dram_map,
	dram_tab,
	DRAM_SIZE,
	DRAM_BLOCK_SIZE,
	DRAM_SIZE / DRAM_BLOCK_SIZE,
	mem_ram_lock,
	mem_ram_unlock,
	&dram_info,
	multi_malloc_api_name(mem_dram)};
multi_malloc_api_make(mem_dram); // 创建API接口

/*******************************************************************************
 * @brief  创建内存池 CCM.
 *******************************************************************************/
#define CCM_SIZE (64)
#define CCM_BLOCK_SIZE (8)

uu64 ccm_map[CCM_SIZE / 8] /*OBJ_SECTION(".ccm")*/;				  // 内存池
uu16 ccm_tab[CCM_SIZE / CCM_BLOCK_SIZE] /*OBJ_SECTION(".sram")*/; // 内存分配表
multi_malloc_info_type ccm_info = {0};							  // 工作信息
uu16 ccm_lock(void) { return 0; }								  // 申请互斥锁
void ccm_unlock(void) {}										  // 释放互斥锁
multi_malloc_api_ref(mem_ccm);									  // 接口引用声明
const multi_malloc_type mem_ccm = {								  // 信息描述
	ccm_map,
	ccm_tab,
	CCM_SIZE,
	CCM_BLOCK_SIZE,
	CCM_SIZE / CCM_BLOCK_SIZE,
	mem_ram_lock,
	mem_ram_unlock,
	&ccm_info,
	multi_malloc_api_name(mem_ccm)};
multi_malloc_api_make(mem_ccm); // 创建API接口

/*******************************************************************************
 * @brief  创建块内存池.
 *******************************************************************************/
#define MEM_BLK1_SIZE 0x50
#define MEM_BLK1_NUM 0x80

#define MEM_BLK2_SIZE 0x120
#define MEM_BLK2_NUM 0x20

#define MEM_BLK3_SIZE 0x440
#define MEM_BLK3_NUM 0x10

#define MEM_BLK4_SIZE 0x1080
#define MEM_BLK4_NUM 4

#define MEM_BLK_BASE (0x20000000 + 0x18000 + 64 * 1024)
#define MEM_BLK1_BASE MEM_BLK_BASE
#define MEM_BLK2_BASE (MEM_BLK1_BASE + MEM_BLK1_SIZE * MEM_BLK1_NUM)
#define MEM_BLK3_BASE (MEM_BLK2_BASE + MEM_BLK2_SIZE * MEM_BLK2_NUM)
#define MEM_BLK4_BASE (MEM_BLK3_BASE + MEM_BLK3_SIZE * MEM_BLK3_NUM)
#define MEM_BLK_END (MEM_BLK4_BASE + MEM_BLK4_SIZE * MEM_BLK4_NUM - 1)
#if MEM_BLK_END >= MEM_BLK_BASE + 64 * 1024
#error MEM BLOCK ADDRESS LIMIT OUT !
#endif

mem_blk_gen(blk_sram);
/*
mem_blk_add(blk_sram, 128, 20, 01);
mem_blk_add(blk_sram, 512, 4, 04);
mem_blk_add_sec(blk_sram, 1024, 4, 05, "sram");
*/
mem_blk_add_addr(blk_sram, MEM_BLK1_SIZE, MEM_BLK1_NUM, 01, MEM_BLK1_BASE);
mem_blk_add_addr(blk_sram, MEM_BLK2_SIZE, MEM_BLK2_NUM, 02, MEM_BLK2_BASE);
mem_blk_add_addr(blk_sram, MEM_BLK3_SIZE, MEM_BLK3_NUM, 03, MEM_BLK3_BASE);
mem_blk_add_addr(blk_sram, MEM_BLK4_SIZE, MEM_BLK4_NUM, 04, MEM_BLK4_BASE);

mem_blk_ext_cfg_make(blk_sram, mem_ram_lock, mem_ram_unlock);

/*******************************************************************************
 * @brief  块内存信息打印.
 *******************************************************************************/
void mem_blk_info(mem_block_ext_cfg_type *ecfg)
{
	mem_block_cfg_type *const *cfg = ecfg->cfg;
	uu32 total = 0, mark_len;

	dbg_print("=======================BLOCK MEM INFO===========================\n");
	cfg++;
	for (; *cfg; cfg++)
	{
		mem_block_cfg_type *cfg_sel = *cfg;
		mark_len = (cfg_sel->block_num + 15) >> 4;

		dbg_print("BLK BASE: %8X, BLK SIZE: %4d, BLK NUM: %3d, USED:%3d, ",
				  (uu32)(cfg_sel->mem_base),
				  cfg_sel->block_size,
				  cfg_sel->block_num,
				  cfg_sel->info->used);
		dbg_u16_print("MARK: ", cfg_sel->mem_mark, mark_len, mark_len + 1);
		total += cfg_sel->block_num * cfg_sel->block_size;
	}
	dbg_print("==================BLOCK MEM INFO END: %dKB=======================\n", total >> 10);
}
